package com.cs589.smscrypto;

import java.io.*;
//import java.util.*;
import java.net.InetAddress;
import java.net.Socket;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.*;

import android.util.Log;

public class Encrypt implements Runnable {
	//this class will talk to the server, provide necessary fields, and encrypt a message:
	Socket socket;
	public void run() 
	{
		try 
		{
			InetAddress serverAddr = InetAddress.getByName("192.168.1.101");

			socket = new Socket(serverAddr, 12311);
			//socket.close();

		}
		catch (Exception e) 
		{
			Log.e("TCP", "C: Error", e);
		}
    }
	
	public byte[] getPublic(String phonenum)
	{
		//Returns pubKey on success, "fail" on failure to receive
		//This method will get the public key from the server of a provided phone number
		try 
		{
			InetAddress serverAddr = InetAddress.getByName("192.168.1.101");

			socket = new Socket(serverAddr, 12311);
			//socket.close();

		}
		catch (Exception e) 
		{
			Log.e("TCP", "C: Error", e);
		}
		try 
		{
			//execute the command on the server:
			String message = "R"+phonenum;

			PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
			out.print(message);
			out.flush();
			
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			int messageLength = Integer.parseInt(in.readLine());
			char[] pubKey = new char[messageLength]; 
			byte[] pubKeyConvert = convertCharArrayToByteArray(pubKey);
			in.read(pubKey, 0, messageLength);
			
			if(pubKey.length == messageLength)
			{
				//this is correct, the size and message length match
				//we now know the public key, return
				return(pubKeyConvert);
			}
			 
		} 
		catch(Exception e) 
		{
			Log.e("TCP", "S: Error", e);
		}
		//fail
		return null;
	}
	public byte[] getPrivate(String phonenum, String deviceID)
	{
		//This method will get the private key from the server provided a phone number and device ID
		try 
		{
			InetAddress serverAddr = InetAddress.getByName("192.168.1.101");

			socket = new Socket(serverAddr, 12311);
			//socket.close();

		}
		catch (Exception e) 
		{
			Log.e("TCP", "C: Error", e);
		}
		try 
		{
			//execute the commmand on the server:
			String message = "A"+phonenum+deviceID;

			PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
			out.print(message);
			out.flush();
			
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			int messageLength = Integer.parseInt(in.readLine());
			char[] privKey = new char[messageLength]; 
			byte[] privKeyConvert = convertCharArrayToByteArray(privKey);
			in.read(privKey, 0, messageLength);
			 
			if(privKey.length == messageLength)
			{
				//this is correct, the size and message length match
				//we now know the private key, return
				return(privKeyConvert);
			}
		} 
		catch(Exception e) 
		{
			Log.e("TCP", "S: Error", e);
		}
		//fail
		return null;
	}
	
	static public byte[] convertCharArrayToByteArray(char[] ca) {
	    byte[] ba = new byte[ca.length * 2];
	    java.nio.ByteBuffer.wrap(ba).asCharBuffer().put(ca);
	    return ba;
	  }
	
	public String encryptMesssage(byte[] pubKey, String textMessage) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IOException
	{
		String encryptedMessage = "";
		//Encrypt the string, return the encrypted result
		
		
		byte[] encodedKey = pubKey;

		X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);

		KeyFactory kf = KeyFactory.getInstance("RSA");
		PublicKey pk = kf.generatePublic(publicKeySpec);

		Cipher rsa = Cipher.getInstance("RSA");

		rsa.init(Cipher.ENCRYPT_MODE, pk);
		OutputStream os = new CipherOutputStream(
		        new FileOutputStream("encrypted.rsa"), rsa);
		
		Writer out = new OutputStreamWriter(os);
		out.write("Hello World!!");
		out.close();
		os.close();
		
		
		return(encryptedMessage);
	}
	public String decryptMessage(byte[] privKey, String encryptedMessage)
	{
		String decryptedMessage = "";
		//Decrypt the string, return the decrypted result
		return(decryptedMessage);
	}
	
}
